const https = require('https');
const querystring = require('querystring');
const crypto = require('crypto');

class Translator {
    constructor(config) {
        this.config = config;
        this.cache = new Map(); // 翻译缓存
    }

    // 翻译单个文本
    async translateText(text, targetLang, sourceLang = 'auto') {
        const cacheKey = `${text}_${sourceLang}_${targetLang}`;
        
        // 检查缓存
        if (this.cache.has(cacheKey)) {
            return this.cache.get(cacheKey);
        }

        // 在线翻译
        try {
            let result;
            
            switch (this.config.api.provider) {
                case 'google':
                    result = await this.translateWithGoogle(text, targetLang, sourceLang);
                    break;
                case 'baidu':
                    result = await this.translateWithBaidu(text, targetLang, sourceLang);
                    break;
                case 'youdao':
                    result = await this.translateWithYoudao(text, targetLang, sourceLang);
                    break;
                default:
                    // 使用免费的Google翻译API
                    result = await this.translateWithGoogle(text, targetLang, sourceLang);
            }

            // 缓存结果
            this.cache.set(cacheKey, result);
            return result;
        } catch (error) {
            // 不在这里打印错误，由上层重试逻辑处理
            throw error; // 重新抛出错误，让调用方处理
        }
    }

    // Google翻译（免费版本）
    async translateWithGoogle(text, targetLang, sourceLang = 'auto') {
        return new Promise((resolve, reject) => {
            const url = 'https://translate.googleapis.com/translate_a/single';
            const params = {
                client: 'gtx',
                sl: sourceLang,
                tl: targetLang,
                dt: 't',
                q: text
            };

            const fullUrl = `${url}?${querystring.stringify(params)}`;
            
            https.get(fullUrl, (res) => {
                let data = '';
                res.on('data', (chunk) => data += chunk);
                res.on('end', () => {
                    try {
                        const result = JSON.parse(data);
                        if (result && result[0] && result[0][0]) {
                            resolve(result[0][0][0]);
                        } else {
                            reject(new Error('翻译结果格式错误'));
                        }
                    } catch (error) {
                        reject(error);
                    }
                });
            }).on('error', reject);
        });
    }

    // 百度翻译
    async translateWithBaidu(text, targetLang, sourceLang = 'auto') {
        // 需要百度翻译API密钥
        if (!this.config.api.apiKey || !this.config.api.apiSecret) {
            throw new Error('百度翻译需要API密钥');
        }
        console.log('暂不支持百度翻译')
        
        // 这里实现百度翻译API调用
        // 由于需要API密钥，暂时返回原文
        return text;
    }

    // 有道翻译
    async translateWithYoudao(text, targetLang, sourceLang = 'auto') {
        // 需要有道翻译API密钥
        if (!this.config.api.apiKey || !this.config.api.apiSecret) {
            throw new Error('有道翻译需要API密钥');
        }
        
        return new Promise((resolve, reject) => {
            try {
                // 有道翻译API参数
                const appKey = this.config.api.apiKey;
                const appSecret = this.config.api.apiSecret;
                const salt = Date.now().toString();
                const curtime = Math.round(Date.now() / 1000).toString();
                
                // 计算签名
                const signStr = appKey + this.truncateQuery(text) + salt + curtime + appSecret;
                const sign = crypto.createHash('sha256').update(signStr).digest('hex');
                
                // 语言代码转换
                const fromLang = this.convertToYoudaoLangCode(sourceLang);
                const toLang = this.convertToYoudaoLangCode(targetLang);
                
                // 请求参数
                const params = {
                    q: text,
                    from: fromLang,
                    to: toLang,
                    appKey: appKey,
                    salt: salt,
                    sign: sign,
                    signType: 'v3',
                    curtime: curtime
                };
                
                const postData = querystring.stringify(params);
                
                const options = {
                    hostname: 'openapi.youdao.com',
                    port: 443,
                    path: '/api',
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'Content-Length': Buffer.byteLength(postData)
                    },
                    timeout: 10000
                };
                
                const req = https.request(options, (res) => {
                    let data = '';
                    res.on('data', (chunk) => data += chunk);
                    res.on('end', () => {
                        try {
                            const result = JSON.parse(data);
                            
                            if (result.errorCode === '0' && result.translation && result.translation.length > 0) {
                                // 清理翻译结果中的特殊字符
                                let translation = result.translation[0];
                                // 移除开头的引号和特殊字符
                                translation = translation.replace(/^["'"']/, '').replace(/["'"']$/, '');
                                resolve(translation);
                            } else {
                                // 不在这里打印错误，由上层重试逻辑处理
                                reject(new Error(`有道翻译失败: ${result.errorCode}`));
                            }
                        } catch (error) {
                            reject(error);
                        }
                    });
                });
                
                req.on('error', (error) => {
                    reject(error);
                });
                
                req.on('timeout', () => {
                    req.destroy();
                    reject(new Error('有道翻译请求超时'));
                });
                
                req.write(postData);
                req.end();
                
            } catch (error) {
                reject(error);
            }
        });
    }
    
    // 截断查询字符串（有道翻译要求）
    truncateQuery(q) {
        const len = q.length;
        if (len <= 20) {
            return q;
        } else {
            return q.substring(0, 10) + len + q.substring(len - 10, len);
        }
    }
    
    // 转换为有道翻译的语言代码
    convertToYoudaoLangCode(lang) {
        return lang;
    }

    // 创建进度条
    createProgressBar(current, total, barWidth = 30) {
        const progress = current / total;
        const filledWidth = Math.round(barWidth * progress);
        const emptyWidth = barWidth - filledWidth;
        
        const filledBar = '█'.repeat(filledWidth);
        const emptyBar = '░'.repeat(emptyWidth);
        const percentage = (progress * 100).toFixed(1);
        
        return `[${filledBar}${emptyBar}] ${percentage}% (${current}/${total})`;
    }

    // 批量翻译（确保100%在线翻译成功）
    async translateBatch(texts, targetLang, sourceLang = 'auto') {
        const results = {};
        const totalTexts = Object.keys(texts).length;
        let currentIndex = 0;
        let successCount = 0;
        let totalRetries = 0;
        const startTime = Date.now(); // 记录开始时间
        
        console.log(`\n🚀 开始翻译到 ${targetLang} 语言`);
        console.log(`📊 总计需要翻译: ${totalTexts} 个词汇`);
        console.log('─'.repeat(60));
        
        for (const [key, text] of Object.entries(texts)) {
            currentIndex++;
            
            // 更新进度条（在同一行实时更新）
            const progressBar = this.createProgressBar(currentIndex, totalTexts);
            process.stdout.write(`\r${progressBar} 正在翻译: ${text}`);
            
            // 尝试翻译，失败时重试（增加重试次数和延迟）
            let translatedText = text;
            let currentRetryCount = 0;
            const maxRetries = 8; // 增加重试次数到8次
            
            while (currentRetryCount <= maxRetries) {
                try {
                    translatedText = await this.translateText(text, targetLang, sourceLang);
                    if (translatedText !== text) {
                        successCount++;
                    }
                    break; // 成功则跳出循环
                } catch (error) {
                    currentRetryCount++;
                    totalRetries++;
                    if (currentRetryCount > maxRetries) {
                        // 只有在重试次数用完后才打印错误信息
                        console.error(`\n❌ 翻译最终失败: ${text} -> ${targetLang}, 错误: ${error.message}`);
                        translatedText = text;
                    } else {
                        // 指数退避策略，延迟时间逐渐增加
                        const baseDelay = 3000; // 基础延迟3秒
                        const delayTime = Math.min(baseDelay * Math.pow(2, currentRetryCount - 1), 30000); // 最大30秒
                        // 在重试时更新进度条状态，不打印错误
                        process.stdout.write(`\r${progressBar} ⚠️ 重试中 (${currentRetryCount}/${maxRetries}): ${text}`);
                        await new Promise(resolve => setTimeout(resolve, delayTime));
                        // 重试后恢复正常显示
                        process.stdout.write(`\r${progressBar} 正在翻译: ${text}`);
                    }
                }
            }
            
            results[key] = translatedText;
            
            // 显示翻译完成状态（在同一行更新）
            const status = translatedText !== text ? '✓ 完成' : '❌ 失败';
            process.stdout.write(`\r${progressBar} ${status}: ${text}`);
            
            // 增加延迟避免API限制
            const delay = 500; // 0.5秒间隔
            await new Promise(resolve => setTimeout(resolve, delay));
        }
        
        const endTime = Date.now(); // 记录结束时间
        const totalTime = ((endTime - startTime) / 1000).toFixed(1); // 计算总时间
        
        // 完成时换行
        console.log('\n');
        
        // 显示最终统计
        console.log('─'.repeat(60));
        console.log(`🎉 ${targetLang} 语言翻译完成！`);
        console.log(`📊 最终统计:`);
        console.log(`   • 总词汇数: ${totalTexts}`);
        console.log(`   • 成功翻译: ${successCount}`);
        console.log(`   • 失败词汇: ${totalTexts - successCount}`);
        console.log(`   • 成功率: ${((successCount / totalTexts) * 100).toFixed(1)}%`);
        console.log(`   • 总重试次数: ${totalRetries}`);
        console.log(`   • 总耗时: ${totalTime}秒`);
        console.log('─'.repeat(60));
        
        return { results, totalTime }; // 返回结果和耗时
    }

    // 获取语言代码映射
    getLanguageCode(lang) {
        const langMap = {
            'en': 'en',
            'zh-CN': 'zh-CN',
            'zh': 'zh-CN',
            'ja': 'ja',
            'japanese': 'ja',
            'ko': 'ko',
            'korean': 'ko',
            'fr': 'fr',
            'french': 'fr',
            'de': 'de',
            'german': 'de',
            'es': 'es',
            'spanish': 'es',
            'ru': 'ru',
            'russian': 'ru'
        };
        
        return langMap[lang] || lang;
    }
}

module.exports = Translator;
